package SinglyLinkedList;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Spliterator;
import java.util.function.Consumer;

public class SinglyLinkedList implements Iterable<Integer> { //整体
    private Node head = null; //头指针

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            Node p = head;

            @Override
            public boolean hasNext() { //是否有下一个元素
                return p != null;
            }

            @Override
            public Integer next() { //返回当前值，并指向下一个元素
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                int v = p.value;
                p = p.next;
                return v;
            }
        };
    }

    //节点类
    private static class Node {
        int value; //值
        Node next; //下一个节点

        public Node(int value, Node next) {
            this.value = value;
            this.next = next;
        }
    }

    public void addFirst(int value) {
        //1.链表为空
        //head = new Node(value,null);
        //链表非空
        head = new Node(value, head);
    }

    public void loop() {
        Node p = head;
        while (p != null) {
            System.out.println(p.value);
            p = p.next;
        }
    }

    public void loop1(Consumer<Integer> consumer) {
        Node p = head;
        while (p != null) {
            consumer.accept(p.value);
            p = p.next;
        }
    }

    public void loop2(Consumer<Integer> consumer) {
        for (Node p = head; p != null; p = p.next) {
            consumer.accept(p.value);
        }
    }
    public void loop3(Consumer<Integer> before,Consumer<Integer> after){
         recursion(head,before,after);
    }
    private void recursion(Node curr,Consumer<Integer> before,Consumer<Integer> after){
        if(curr == null){
            return;
        }
        before.accept(curr.value);
        recursion(curr.next,before,after);
        after.accept(curr.value);
    }
    private Node findNode() {
        Node p = head;
        while (p != null) {
            if (p.next == null) {
                return p;
            }
            p = p.next;
        }
        return null;
    }

    public void addLast(int value) {
        Node last = findNode();
        if (last == null) {
            addFirst(value);
            return;
        }
        last.next = new Node(value, null);
    }

    private Node findNode(int index) {
        int i = 0;
        Node p = head;
        while (p != null) {
            if (i == index) {
                return p;
            }
            p = p.next;
            i++;
        }
        return null; //没找到
    }

    public int get(int index) {
        Node a = findNode(index);
        if (a == null) {
         throw new IllegalArgumentException(
                 String.format("index[%d] 不合法%n",index)
         );
        }
        return a.value;
    }
    public void insert(int index,int value){
        if(index == 0){
            addFirst(value);
            return;
        }
        Node b = findNode(index-1);
        if(b == null){
            throw new IllegalArgumentException(
                    String.format("index[%d] 不合法%n",index)
            );
        }
        b.next = new Node(value,b.next);
    }
    public void removeFirst(){
        if(head == null){
            throw new IllegalArgumentException(
                    String.format("index[%d] 不合法%n",0)
            );
        }
        head = head.next;
    }
    public void remove(int index){
        if(index == 0 ){
            removeFirst();
            return;
        }
        Node c =findNode(index-1);
        if(c == null){
            throw new IllegalArgumentException(
                    String.format("index[%d] 不合法%n",index)
            );
        }
        Node removed = c.next;
        if(removed == null){
            throw new IllegalArgumentException(
                    String.format("index[%d] 不合法%n",index)
            );
        }
        c.next = removed.next;
    }
}